package com.wangmeng.book.client.service;

import com.sun.xml.internal.ws.util.StringUtils;
import com.wangmeng.book.client.MainFrame;
import com.wangmeng.book.server.Command;
import com.wangmeng.book.server.CommandResult;
import com.wangmeng.book.utils.ConstValueUtils;
import com.wangmeng.book.utils.MessageDigestHelper;
import net.sf.json.JSONArray;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * User: 王猛
 * Date: 13-9-24
 */
public class CommandService {
    private static final AtomicBoolean isLogin = new AtomicBoolean(false);
    private static final CommandService cmdService = new CommandService();
    private static final ConcurrentHashMap userData = new ConcurrentHashMap();
    private static String SERVER_HOST = "localhost";
    private static Integer SERVER_PORT = 1818;

    static {
        Properties prop = new Properties();
        try {
            prop.load(CommandService.class.getClassLoader().getResourceAsStream("config.properties"));
            String host = prop.getProperty("SERVER.HOST");
            if (host != null && host.trim().length() > 0) {
                SERVER_HOST = host;
            }
            String port = prop.getProperty("SERVER.PORT");
            if (port != null && port.trim().length() > 0) {
                SERVER_PORT = Integer.valueOf(port.trim());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Socket connSocket;
    private ObjectOutputStream objOut;
    private ObjectInputStream objIn;
    private AtomicInteger status = new AtomicInteger(0);

    private CommandService() {

    }

    public static CommandService getInstance() {
        return cmdService;
    }

    public boolean login(String userName, String pass) {
        boolean result = false;
        try {
            connSocket = new Socket(SERVER_HOST, SERVER_PORT);
            objOut = new ObjectOutputStream(connSocket.getOutputStream());
            objIn = new ObjectInputStream(connSocket.getInputStream());
            Command cmd = new Command();
            cmd.setCmdCode(Command.CMD_LOGIN);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("username", userName);
            Long time = new Date().getTime() / 1000;
            pass = MessageDigestHelper.digestBySHA(MessageDigestHelper.digestBySHA(pass) + time.toString());
            data.put("password", pass);
            data.put("time", time);
            cmd.setData(data);
            objOut.writeObject(cmd);
            objOut.reset();
            CommandResult cr = (CommandResult) objIn.readObject();
            if (cr != null && cr.getCode() == CommandResult.CODE_SUCCESS) {
                status.compareAndSet(1, 2);
                isLogin.set(true);
                synchronized (userData) {
                    userData.putAll(cr.getData());
                }
                result = true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    public JSONArray listBook(int page, int pageSize, List<Integer> status, String orderBy, Map<String, Object> exParam) {
        Command cmd = new Command();
        cmd.setCmdCode(Command.CMD_BOOK_LIST);
        JSONArray result = null;
        try {
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("page", page);
            param.put("pageSize", pageSize);
            param.put("status", status);
            param.put("orderBy", orderBy);
            param.putAll(exParam);
            cmd.setData(param);
            objOut.writeObject(cmd);
            objOut.reset();
            CommandResult cr = (CommandResult) objIn.readObject();
            if (cr != null) {
                if (cr.getCode() == ConstValueUtils.CODE_SUCCESS) {
                    String jsonData = (String) cr.getData().get("data");
                    if (jsonData.length() > 0) {
                        result = JSONArray.fromObject(jsonData);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public JSONArray listBookPartition() {
        Command cmd = new Command();
        cmd.setCmdCode(Command.CMD_LIST_PARTITION);
        JSONArray result = null;
        try {
            objOut.writeObject(cmd);
            objOut.reset();
            CommandResult cr = (CommandResult) objIn.readObject();
            if (cr != null) {
                if (cr.getCode() == ConstValueUtils.CODE_SUCCESS) {
                    String jsonData = (String) cr.getData().get("data");
                    if (jsonData.length() > 0) {
                        result = JSONArray.fromObject(jsonData);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public Object receiveData(List<Map> items) {
        if (items != null) {
            Command cmd = new Command();
            cmd.setCmdCode(Command.CMD_BOOK_RECEIVE);
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("data", items);
            cmd.setData(params);
            try {
                objOut.writeObject(cmd);
                objOut.reset();
                CommandResult cr = (CommandResult) objIn.readObject();
                if (cr != null) {
                    if (cr.getCode() == ConstValueUtils.CODE_SUCCESS) {
                        Object backData = cr.getData().get("data");
                        return backData;
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public Object publishBook(int opType, List<Integer> idList) {
        if (opType > 0) {
            Command cmd = new Command();
            cmd.setCmdCode(Command.CMD_BOOK_PUBLISH);
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("type", opType);
            params.put("idList", idList);
            cmd.setData(params);
            try {
                objOut.writeObject(cmd);
                objOut.reset();
                CommandResult cr = (CommandResult) objIn.readObject();
                if (cr != null) {
                    if (cr.getCode() == ConstValueUtils.CODE_SUCCESS) {
                        Object backData = cr.getData().get("data");
                        return backData;
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return 0;
    }

    public Object rejectData(List<Map> items) {
        if (items != null) {
            Command cmd = new Command();
            cmd.setCmdCode(Command.CMD_BOOK_REJECT);
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("data", items);
            cmd.setData(params);
            try {
                objOut.writeObject(cmd);
                objOut.reset();
                CommandResult cr = (CommandResult) objIn.readObject();
                if (cr != null) {
                    if (cr.getCode() == ConstValueUtils.CODE_SUCCESS) {
                        Object backData = cr.getData().get("data");
                        return backData;
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public void logout() {
        if (isLogin.compareAndSet(true, false)) {
            Command cmd = new Command();
            cmd.setCmdCode(Command.CMD_LOGOUT);
            try {
                objOut.writeObject(cmd);
                objOut.reset();
                CommandResult cr = (CommandResult) objIn.readObject();
//                if (connSocket.isConnected()) {
//                    connSocket.close();
//                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public int startJobByType(int jobType, Integer delay, Integer period) {
        try {
            Command cmd = new Command();
            cmd.setCmdCode(Command.CMD_JOB_START);
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("job_type", jobType);
            params.put("delay", delay);
            params.put("period", period);
            cmd.setData(params);
            objOut.writeObject(cmd);
            objOut.reset();
            CommandResult cr = (CommandResult) objIn.readObject();
            return cr.getCode();
        } catch (Exception e) {
            e.printStackTrace();
            return ConstValueUtils.CODE_EXCEPTION;
        }
    }

    public boolean isLogin() {
        return isLogin.get();
    }

    public Object getUserData(String key) {
        return userData.get(key);
    }
}
